home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / xanim / xanim_pfx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-02  |  16.6 KB  |  639 lines

  1.  
  2. /*
  3.  * xanim_pfx.c
  4.  *
  5.  * Copyright (C) 1992,1993,1994 by Mark Podlipec.
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  *
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim_pfx.h"
  19. #include "xanim_iff.h"
  20.  
  21. LONG Is_PFX_File();
  22. ULONG PFX_Read_File();
  23. void PFX_Setup_CMAP();
  24. void PFX_Extract_Images();
  25. ULONG UTIL_Get_MSB_Long();
  26. ULONG UTIL_Get_MSB_UShort();
  27. XA_CHDR *ACT_Get_CMAP();
  28. XA_ACTION *ACT_Get_Action();
  29. void ACT_Setup_Mapped();
  30. void ACT_Add_CHDR_To_Action();
  31.  
  32.  
  33. static PFX_PLAY_HDR *pfx_play_stack,*pfx_play_start,*pfx_play_lcur;
  34.  
  35. static XA_CHDR *pfx_chdr;
  36. static ColorReg pfx_cmap[256];
  37.  
  38. #define PFX_DEFAULT_TIME 17
  39. static LONG pfx_time;
  40. static PFX_RCHG_HDR *pfx_images;
  41.  
  42. static ULONG pfx_imagex,pfx_imagey,pfx_imagec,pfx_imaged;
  43.  
  44. /*
  45.  *
  46.  */
  47. LONG Is_PFX_File(filename)
  48. char *filename;
  49. {
  50.   FILE *fin;
  51.   ULONG data;
  52.  
  53.   if ( (fin=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE);
  54.  
  55.   data = UTIL_Get_MSB_Long(fin);  /* read past size */
  56.   data = UTIL_Get_MSB_Long(fin); /* read magic */
  57.   fclose(fin);
  58.   if (data == pfx_RCHG) return(TRUE);
  59.   return(FALSE);
  60. }
  61.  
  62. void PFX_PUSH_PLAY_HDR(p)
  63. PFX_PLAY_HDR *p;
  64. {
  65.   PFX_PLAY_HDR *temp;
  66.  
  67.   temp = (PFX_PLAY_HDR *) malloc(sizeof(PFX_PLAY_HDR));
  68.   if (temp == 0) TheEnd1("PFX_PUSH_PLAY_HDR: malloc failed\n");
  69.   temp->type = p->type;
  70.   temp->data = p->data;
  71.   temp->count = 0;
  72.   temp->next = 0;
  73.   temp->loop = 0;
  74.   if (pfx_play_start == 0) pfx_play_start = temp;
  75.   else pfx_play_lcur->next = temp;
  76.   pfx_play_lcur = temp;
  77.  
  78.  DEBUG_LEVEL2 fprintf(stderr,"PUSHING %c%c%c%c", ((p->type >> 24) & 0xff),
  79.     ((p->type >> 16) & 0xff), ((p->type >> 8) & 0xff), ((p->type) & 0xff) );
  80.  DEBUG_LEVEL2 fprintf(stderr," data=%lx ptr=%lx\n",
  81.                     p->data,(ULONG)pfx_play_lcur);
  82.  
  83.     /* stack knows where it's duplicate is on play list */
  84.   p->loop = pfx_play_lcur;  
  85.   p->next = pfx_play_stack;
  86.   pfx_play_stack = p;
  87. }
  88.  
  89. PFX_PLAY_HDR *PFX_POP_PLAY_HDR()
  90. {
  91.   PFX_PLAY_HDR *p;
  92.   p = pfx_play_stack;
  93.   if (p != 0) pfx_play_stack = pfx_play_stack->next;
  94.   return(p);
  95. }
  96.  
  97. PFX_RCHG_HDR *PFX_Alloc_RCHG()
  98. {
  99.   PFX_RCHG_HDR *temp;
  100.  
  101.   temp = (PFX_RCHG_HDR *)malloc(sizeof(PFX_RCHG_HDR));
  102.   if (temp == 0) TheEnd1("PFX_Alloc_RCHG malloc error\n");
  103.   temp->orig = 0;
  104.   temp->dest = 0;
  105.   temp->len  = 0;
  106.   temp->data = 0;
  107.   temp->next = 0;
  108.   return(temp);
  109. }
  110.  
  111. PFX_FRAM_HDR *PFX_Alloc_FRAM()
  112. {
  113.   PFX_FRAM_HDR *temp;
  114.   temp = (PFX_FRAM_HDR *)malloc(sizeof(PFX_FRAM_HDR));
  115.   if (temp == 0) TheEnd1("PFX_Alloc_FRAM malloc error\n");
  116.   temp->frame = 0;
  117.   temp->time  = 0;
  118.   temp->next = 0;
  119.   return(temp);
  120. }
  121.  
  122.  
  123. ULONG PFX_Read_File(fname,anim_hdr)
  124. char *fname;
  125. XA_ANIM_HDR *anim_hdr;
  126. {
  127.   FILE *fin;
  128.   PFX_RCHG_HDR  *first_rchg,*cur_rchg;
  129.   PFX_RCHG_HDR  *first_parm,*cur_parm;
  130.   PFX_FRAM_HDR *first_fram,*cur_fram;
  131.   ULONG pfx_max_rchg;
  132.   ULONG pfx_xflag,pfx_yflag,pfx_cflag,pfx_rchg_flag;
  133.   ULONG d,chid,chlen;
  134.   ULONG frame_count;
  135.   PFX_PLAY_HDR *pfx_play_temp;
  136.  
  137.  
  138.   pfx_play_stack = 0;
  139.   pfx_play_start = 0;
  140.   pfx_play_lcur  = 0;
  141.  
  142.   pfx_chdr = 0;
  143.   pfx_time = PFX_DEFAULT_TIME;
  144.   pfx_images = 0;
  145.   pfx_imagex = 0;
  146.   pfx_imagey = 0;
  147.   pfx_imagec = 0;
  148.   pfx_imaged = 0;
  149.  
  150.   first_rchg = cur_rchg = 0;
  151.   first_parm = cur_parm = 0;
  152.   pfx_max_rchg = 0;
  153.   pfx_xflag = FALSE;
  154.   pfx_yflag = FALSE;
  155.   pfx_cflag = FALSE;
  156.  
  157.   if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0)
  158.   {
  159.     fprintf(stderr,"Can't open PFX File %s for reading\n",fname);
  160.     return(FALSE);
  161.   }
  162.  
  163.   d = UTIL_Get_MSB_Long(fin);   /* probably version number */
  164.   chid = UTIL_Get_MSB_Long(fin); /* get chunk id */
  165.   chlen = UTIL_Get_MSB_Long(fin); /* get chunk length */
  166.   while(chid == pfx_RCHG)
  167.   {
  168.     LONG ret;
  169.     ULONG orig,dest,garb;
  170.     PFX_RCHG_HDR  *tmp_rchg;
  171.     UBYTE *data;
  172.  
  173.     orig = UTIL_Get_MSB_UShort(fin);
  174.     dest = UTIL_Get_MSB_UShort(fin);
  175.     garb = UTIL_Get_MSB_Long(fin);  /* orig ptr or id or ?? */
  176.     garb = UTIL_Get_MSB_Long(fin);  /* dest ptr or id or ?? */
  177.     garb = UTIL_Get_MSB_UShort(fin); /* always 0xffff */
  178.     DEBUG_LEVEL1 fprintf(stderr,"RCHG %lx  <%ld %ld>\n",chlen,orig,dest);
  179.     chlen -= 14;
  180.  
  181.     data = (UBYTE *)malloc(chlen);
  182.     if (data == 0) TheEnd1("PFX: rchg data malloc failed\n");
  183.     ret = fread((char *)(data),1,chlen,fin);
  184.     if (ret != chlen) TheEnd1("PFX: rchg data read failed\n");
  185.  
  186.     tmp_rchg = PFX_Alloc_RCHG();
  187.     tmp_rchg->orig = orig;    
  188.     tmp_rchg->dest = dest;    
  189.     tmp_rchg->len = chlen;    
  190.     tmp_rchg->data = data;
  191.  
  192.     if (first_rchg == 0) first_rchg = cur_rchg = tmp_rchg;
  193.     else
  194.     {
  195.       cur_rchg->next = tmp_rchg;
  196.       cur_rchg = tmp_rchg;
  197.     }
  198.     if (orig > pfx_max_rchg) pfx_max_rchg = orig;
  199.     if (dest > pfx_max_rchg) pfx_max_rchg = dest;
  200.  
  201.     chid = UTIL_Get_MSB_Long(fin); /* get chunk id */
  202.     chlen = UTIL_Get_MSB_Long(fin); /* get chunk length */
  203.   }
  204.  
  205.   while(chid == pfx_PARM)
  206.   {
  207.     LONG ret;
  208.     ULONG pnum,res1,res2;
  209.     PFX_RCHG_HDR  *tmp_parm;
  210.     UBYTE *data;
  211.  
  212.     pnum = UTIL_Get_MSB_UShort(fin);  /* parm number */
  213.     res1 = UTIL_Get_MSB_UShort(fin);  /* ??? */
  214.     res2 = UTIL_Get_MSB_UShort(fin);   /* ??? */
  215.     chlen -= 6;
  216.  
  217.     data = (UBYTE *)malloc(chlen);
  218.     if (data == 0) TheEnd1("PFX: parm data malloc failed\n");
  219.     ret = fread((char *)(data),1,chlen,fin);
  220.     if (ret != chlen) TheEnd1("PFX: parm data read failed\n");
  221.  
  222.     DEBUG_LEVEL1 fprintf(stderr,"PARM %lx\n",chlen);
  223.     DEBUG_LEVEL2 fprintf(stderr,"     %s\n",data);
  224.      
  225.     tmp_parm = PFX_Alloc_RCHG();
  226.     tmp_parm->orig = pnum;
  227.     tmp_parm->dest = res1;
  228.     tmp_parm->len = chlen;
  229.     tmp_parm->data = data;
  230.  
  231.     if (first_parm == 0) first_parm = cur_parm = tmp_parm;
  232.     else
  233.     {
  234.       cur_parm->next = tmp_parm;
  235.       cur_parm = tmp_parm;
  236.     }
  237.  
  238.     chid = UTIL_Get_MSB_Long(fin); /* get chunk id */
  239.     chlen = UTIL_Get_MSB_Long(fin); /* get chunk length */
  240.   }
  241.  
  242.   if (chid != pfx_STMT)
  243.   { 
  244.     fprintf(stderr,"PFX: confused\n");
  245.     return(FALSE);
  246.   }
  247.  
  248.  
  249.   first_fram = cur_fram = 0;
  250.   frame_count = 0;
  251.  
  252.   pfx_rchg_flag = FALSE;
  253.   while(chlen && !feof(fin) )
  254.   {
  255.     chid = UTIL_Get_MSB_Long(fin);  chlen-=4; /* get script id */
  256.  
  257.     if (chid == pfx_A_B)
  258.     {
  259.       PFX_PLAY_HDR *p;
  260.       p = PFX_POP_PLAY_HDR();
  261.       if (p == 0) TheEnd1("PFX Play List: stack empty err1\n");
  262.       if (pfx_play_temp == 0) TheEnd1("PFX Play List: stack empty err2\n");
  263.       DEBUG_LEVEL1 fprintf(stderr,"POP %c%c%c%c\n", 
  264.     ((p->type >> 24) & 0xff), ((p->type >> 16) & 0xff), 
  265.     ((p->type >> 8) & 0xff), ((p->type) & 0xff) );
  266.       if (p->type == pfx_REPE) /* point back to just after REPE */
  267.       {
  268.         if (p->loop->next != 0) pfx_play_temp->loop = p->loop->next;
  269.         else TheEnd1("PFX_Loop: hosed\n");
  270.         DEBUG_LEVEL1 fprintf(stderr,"   loop to %c%c%c%c", 
  271.      ((p->loop->next->type >> 24) & 0xff),
  272.      ((p->loop->next->type >> 16) & 0xff), 
  273.      ((p->loop->next->type >> 8) & 0xff),
  274.      ((p->loop->next->type) & 0xff) );
  275.         DEBUG_LEVEL1 fprintf(stderr,"   count=%lx\n",p->loop->next->data);
  276.       }
  277.       FREE(p,0x6000); p=0;
  278.     }
  279.     else
  280.     {
  281.       pfx_play_temp = (PFX_PLAY_HDR *)malloc(sizeof(PFX_PLAY_HDR));
  282.       if (pfx_play_temp == 0) TheEnd1("PFX: malloc PFX_PLAY_HDR error\n");
  283.       pfx_play_temp->type = chid;
  284.       pfx_play_temp->data = 0;
  285.       pfx_play_temp->loop = 0;
  286.       pfx_play_temp->next = 0;
  287.       switch(chid)
  288.       {
  289.     case pfx_INIT:
  290.     case pfx_GLOC:
  291.     case pfx_GLOV:
  292.     case pfx_REPE:
  293.         PFX_PUSH_PLAY_HDR(pfx_play_temp);
  294.         break;
  295.     case pfx_BITP:
  296.     case pfx_XDIM:
  297.     case pfx_YDIM:
  298.     case pfx_DURA:
  299.     case pfx_HIGH:
  300.     case pfx_FLAC:
  301.     case pfx_COUN:
  302.     case pfx_INTE:
  303.     case pfx_AUST:
  304.     case pfx_SPDU:
  305.     case pfx_SLWD:
  306.         pfx_play_temp->data = UTIL_Get_MSB_Long(fin); chlen-=4;
  307.         PFX_PUSH_PLAY_HDR(pfx_play_temp);
  308.         break;
  309.     case pfx_PALL:
  310.     case pfx_FRAM:
  311.     case pfx_FILE:
  312.         pfx_play_temp->data = UTIL_Get_MSB_UShort(fin); chlen-=2;
  313.         PFX_PUSH_PLAY_HDR(pfx_play_temp);
  314.         break;
  315.     default:
  316.         fprintf(stdout,"PFX read: Unknown STMT chid %lx\n",chid);
  317.         return(FALSE);
  318.         break;
  319.       }
  320.     }
  321.   } /* end of while for reading play list */
  322.  
  323.   fclose(fin);
  324.   /* free up Play List stack just in case it's not already freed up */
  325.   {
  326.     PFX_PLAY_HDR *p;
  327.     do
  328.     {
  329.       p = PFX_POP_PLAY_HDR();
  330.       if (p != 0) 
  331.       {
  332.         FREE(p,0x6000); p=0;
  333.         fprintf(stderr,"PFX Warning: play list different than expected\n");
  334.       }
  335.     } while(p != 0);
  336.   }
  337.  
  338.  
  339. /* loop through play list to create frame list */
  340.   pfx_play_lcur = pfx_play_start;
  341.   while(pfx_play_lcur != 0)
  342.   {
  343.    ULONG garb;
  344.  
  345.     chid = pfx_play_lcur->type;
  346.     switch(chid)
  347.     {
  348.       case pfx_INIT:
  349.       case pfx_GLOC:
  350.       case pfx_GLOV:
  351.       case pfx_REPE: /* REPEAT: for now must be followed by COUN */
  352.       case pfx_FILE: /* NOTE: this is comment only */
  353.         break;
  354.       case pfx_BITP: /* Num of Bitplanes */
  355.         pfx_imaged = pfx_play_lcur->data;
  356.         break;
  357.       case pfx_XDIM: /* X size */
  358.         pfx_imagex = pfx_play_lcur->data;
  359.         pfx_xflag = TRUE;
  360.         break;
  361.       case pfx_YDIM: /* Y size */
  362.         pfx_imagey = pfx_play_lcur->data;
  363.         pfx_yflag = TRUE;
  364.         break;
  365.       case pfx_HIGH: /* ??? */
  366.       case pfx_FLAC: /* ??? */
  367.       case pfx_INTE: /* Interlace flag */
  368.       case pfx_AUST: /* don't know */
  369.         break;
  370.       case pfx_DURA: /* ?Duration between frames */
  371.         garb = pfx_play_lcur->data; if (garb == 0) garb = 1;
  372.         pfx_time = garb * PFX_DEFAULT_TIME;
  373.         break;
  374.       case pfx_SPDU: /* speed up by this much */
  375.         garb = pfx_play_lcur->data;
  376.         pfx_time += garb * PFX_DEFAULT_TIME;
  377.         break;
  378.       case pfx_SLWD: /* slow down by this much */
  379.         garb = pfx_play_lcur->data;
  380.         pfx_time -= garb * PFX_DEFAULT_TIME;
  381.         if (pfx_time <= 0) pfx_time = 1;
  382.         break;
  383.       case pfx_PALL: /* CMAP parm id */
  384.         garb = pfx_play_lcur->data;
  385.         PFX_Setup_CMAP(garb,first_parm);
  386.         pfx_cflag = TRUE;
  387.         break;
  388.       case pfx_COUN:
  389.         garb = pfx_play_lcur->data;
  390.             /* 0x3b9ac9ff for example is mouse button */
  391.         if (garb >= 0x100) garb = 1;
  392.         pfx_play_lcur->count = garb;
  393.         break;
  394.       case pfx_FRAM:
  395.         garb = pfx_play_lcur->data;
  396.         if (first_fram == 0)
  397.           first_fram = cur_fram = PFX_Alloc_FRAM();
  398.         else
  399.         {
  400.           cur_fram->next = PFX_Alloc_FRAM();
  401.           cur_fram = cur_fram->next;
  402.         }
  403.         cur_fram->frame = garb;
  404.         cur_fram->time  = XA_GET_TIME(pfx_time);
  405.         frame_count++;
  406.         break;
  407.       default: 
  408.         fprintf(stdout,"PFX frame lst: Unknown STMT chid %lx\n",chid);
  409.         return(FALSE);
  410.         break;
  411.      } /* end switch */
  412.      if (   (pfx_xflag==TRUE) && (pfx_yflag==TRUE) 
  413.          && (pfx_cflag==TRUE) && (pfx_rchg_flag==FALSE))
  414.      {
  415.        pfx_rchg_flag = TRUE;
  416.        PFX_Extract_Images(anim_hdr,first_rchg,pfx_max_rchg);
  417.      }
  418.      if (pfx_play_lcur->loop != 0) 
  419.      { 
  420.        PFX_PLAY_HDR *p;
  421.        p = pfx_play_lcur->loop;
  422.        DEBUG_LEVEL2 fprintf(stderr,"PFX frame loop cnt=%lx\n",p->count);
  423.        p->count--;
  424.        if (p->count > 0) pfx_play_lcur = p; /* goto COUN */
  425.      } 
  426.  
  427.      pfx_play_lcur = pfx_play_lcur->next;
  428.    } /* end of while STMT */
  429.  
  430.    /* Free up play list */
  431.    { 
  432.      PFX_PLAY_HDR *p;
  433.      while(pfx_play_start) 
  434.      {
  435.        p = pfx_play_start;
  436.        pfx_play_start = pfx_play_start->next;
  437.        FREE(p,0x6000); p=0;
  438.      }
  439.    }
  440.  
  441.  {
  442.    PFX_FRAM_HDR *ptr_fram,*tmp_fram;
  443.    ULONG i;
  444.  
  445.    anim_hdr->frame_lst = 
  446.     (XA_FRAME *)malloc(sizeof(XA_FRAME) * (frame_count + 1));
  447.    if (anim_hdr->frame_lst == NULL)
  448.         TheEnd1("PFX_ANIM: couldn't malloc for frame_lst\0");
  449.  
  450.    DEBUG_LEVEL3 fprintf(stderr,"PFX frame List(%ld): ",frame_count);
  451.    ptr_fram = first_fram;
  452.    for(i=0; i<frame_count; i++)
  453.    {  /* frames start at 1, nothing is at 0 */
  454.      anim_hdr->frame_lst[i].act  = pfx_images[ptr_fram->frame].act;
  455.      anim_hdr->frame_lst[i].time = ptr_fram->time;
  456.  
  457.      DEBUG_LEVEL3 fprintf(stderr,"<%ld>",ptr_fram->frame);
  458.      tmp_fram = ptr_fram;
  459.      ptr_fram = ptr_fram->next;
  460.      FREE(tmp_fram,0x6000);
  461.    }
  462.    if (ptr_fram != 0) 
  463.      fprintf(stderr," FRAME stuff: ptr_fram %lx non_zero\n",(ULONG)ptr_fram);
  464.    DEBUG_LEVEL3 fprintf(stderr,"\n");
  465.    anim_hdr->frame_lst[frame_count].time = 0;
  466.    anim_hdr->frame_lst[frame_count].act  = 0;
  467.    anim_hdr->loop_frame = 0;
  468.    anim_hdr->last_frame = frame_count - 1;
  469.    anim_hdr->imagex = pfx_imagex;
  470.    anim_hdr->imagey = pfx_imagey;
  471.    anim_hdr->imagec = pfx_imagec;
  472.    anim_hdr->imaged = pfx_imaged;
  473.  }
  474.  
  475.  { /* FREE PARM STRUCTURES */
  476.    PFX_RCHG_HDR *tmp,*tmp1;
  477.  
  478.    if (pfx_images != 0) FREE(pfx_images,0x6000); /* free up image structures */
  479.    pfx_images=0;
  480.    tmp = first_parm;
  481.    while(tmp) 
  482.    { 
  483.      tmp1 = tmp; 
  484.      tmp = tmp->next;
  485.      FREE(tmp1->data,0x6000);
  486.      FREE(tmp1,0x6000);
  487.    }
  488.    first_parm=0;
  489.  }
  490.  return(TRUE);
  491. }
  492.  
  493.  
  494. void PFX_Extract_Images(anim_hdr,first_rchg,pfx_max_rchg)
  495. XA_ANIM_HDR *anim_hdr;
  496. PFX_RCHG_HDR *first_rchg;
  497. ULONG pfx_max_rchg;
  498. {
  499.   ULONG psize,i;
  500.   UBYTE *data,*pic;
  501.   PFX_RCHG_HDR *tmp_rchg;
  502.  
  503.   psize = pfx_imagex * pfx_imagey;
  504.  
  505.   pfx_max_rchg++;  /* add 0 up front */
  506.   pfx_images = (PFX_RCHG_HDR *)malloc(pfx_max_rchg * sizeof(PFX_RCHG_HDR));
  507.   if (pfx_images == 0) TheEnd1("PFX: malloc failed 1\n");
  508.   for(i=0; i<pfx_max_rchg;i++) 
  509.   {
  510.     pfx_images[i].orig = 0; 
  511.     pfx_images[i].data = 0;
  512.   }
  513.   pfx_images[0].orig = 1; /* indicate it is used */ 
  514.  
  515.   tmp_rchg = first_rchg;
  516.   while(tmp_rchg)
  517.   {
  518.     ULONG orig,dest,len;
  519.     ULONG b_cnt,a_cnt,offset,d,dmask;
  520.     PFX_RCHG_HDR *tmp1_rchg;
  521.  
  522.     orig = tmp_rchg->orig;
  523.     dest = tmp_rchg->dest;
  524.     len  = tmp_rchg->len;
  525.     data = tmp_rchg->data;
  526.     DEBUG_LEVEL2 fprintf(stderr,"PFX Extracting %ld %ld\n",orig,dest);
  527.  
  528.  
  529.     /* new image */
  530.     if ( (pfx_images[orig].orig == 0) || (pfx_images[dest].orig == 0 ) )
  531.     {
  532.       pic = (UBYTE *)malloc( XA_PIC_SIZE(psize) );
  533.       if (pic == 0) TheEnd1("PFX: malloc failed 2\n");
  534.  
  535.       if (orig == 0) memset((char *)(pic),0x00,psize);
  536.       else
  537.       {
  538.         if (pfx_images[orig].orig == 0) 
  539.         { 
  540.           i = orig; orig = dest; dest = i;
  541.         }
  542.     if (pfx_images[orig].orig == 0)
  543.         { 
  544.       fprintf(stderr,"PFX orig doesn't exist yet. faking it.\n");
  545.       memset((char *)(pic),0x00,psize);
  546.         }
  547.     else memcpy((char *)(pic),(char *)(pfx_images[orig].data),psize);
  548.       } 
  549.  
  550.       dmask = 0x01;
  551.       while(len)
  552.       {
  553.         UBYTE *ptr;
  554.         b_cnt = (ULONG)(*data++) << 8;   b_cnt |= (ULONG)(*data++);  len-=2;
  555.         DEBUG_LEVEL3 fprintf(stderr,"b_cnt = %ld\n",b_cnt);
  556.         while(len && b_cnt)
  557.         {
  558.           offset = (ULONG)(*data++) << 8; offset |= (ULONG)(*data++);  len-=2;
  559.           a_cnt = (ULONG)(*data++) << 8;  a_cnt |= (ULONG)(*data++);  len-=2;
  560.           DEBUG_LEVEL4 fprintf(stderr,"<%lx %lx> ",offset,a_cnt);
  561.           ptr = (UBYTE *)(pic + (offset * 8));
  562.       for(i = 0; i <= a_cnt; i++)
  563.       {
  564.             d = (ULONG)(*data++) << 8;  d |= (ULONG)(*data++);  len-=2;
  565.         IFF_Short_Mod(ptr,d,dmask,1);
  566.             ptr += pfx_imagex;
  567.           }
  568.           b_cnt--;
  569.         }
  570.         DEBUG_LEVEL4 fprintf(stderr,"\n\n");
  571.         dmask <<= 1;  /* move to next bitplane */
  572.       }
  573.       if (b_cnt != 0) fprintf(stderr,"b_cnt nonzero\n");
  574.  
  575.       pfx_images[dest].orig = dest;
  576.       pfx_images[dest].data = pic;
  577.       DEBUG_LEVEL2 fprintf(stderr,"New Image pfx_images[deset] = %ld\n",dest);
  578.     } /* new image */
  579.  
  580.     tmp1_rchg = tmp_rchg;
  581.     tmp_rchg = tmp_rchg->next; /* move to next image */
  582.     FREE(tmp1_rchg->data,0x6000); tmp1_rchg->data=0;
  583.     FREE(tmp1_rchg,0x6000); tmp1_rchg=0;
  584.  
  585.   } /* end of while rchg_hdr's */
  586.  
  587.   for(i=1; i<pfx_max_rchg; i++)
  588.   {
  589.     XA_ACTION *act;
  590.     
  591.     if (pfx_images[i].data == 0) fprintf(stderr,"ERROR: im not completed\n");
  592.     act = ACT_Get_Action(anim_hdr);
  593.     pfx_images[i].act = act;
  594.     ACT_Setup_Mapped(act, pfx_images[i].data,
  595.     pfx_chdr,0,0,pfx_imagex,pfx_imagey,pfx_imagex,pfx_imagey,FALSE,0,
  596.     TRUE,TRUE,FALSE);
  597.     ACT_Add_CHDR_To_Action(act,pfx_chdr);
  598.   }
  599. } /* end of function */
  600.  
  601.        
  602. void PFX_Setup_CMAP(cmap_id,first_parm)
  603. ULONG cmap_id;
  604. PFX_RCHG_HDR *first_parm;
  605. {
  606.   ULONG found_flag,i;
  607.   UBYTE *ptr;
  608.   PFX_RCHG_HDR *tmp_parm;
  609.  
  610.   found_flag = FALSE;
  611.   tmp_parm = first_parm;
  612.  
  613.   while(tmp_parm && (found_flag==FALSE))
  614.   {
  615.     if (tmp_parm->orig == cmap_id) found_flag = TRUE;
  616.     else tmp_parm = tmp_parm->next;
  617.   }
  618.  
  619.   if (found_flag == FALSE) TheEnd1(stderr,"PFX CMAP: not found\n");
  620.  
  621.   pfx_imagec = tmp_parm->len--;
  622.   pfx_imagec /= 3;
  623.   ptr = tmp_parm->data;
  624.   for(i=0;i<pfx_imagec;i++)
  625.   {
  626.     ULONG d;
  627.     d = (*ptr++) - 48; if (d > 9) d -= 7;   /* ascii to integer */
  628.     pfx_cmap[i].red =  d & 0x0f;
  629.     d = (*ptr++) - 48; if (d > 9) d -= 7;   /* ascii to integer */
  630.     pfx_cmap[i].green =  d & 0x0f;
  631.     d = (*ptr++) - 48; if (d > 9) d -= 7;   /* ascii to integer */
  632.     pfx_cmap[i].blue =  d & 0x0f;
  633.     DEBUG_LEVEL2 fprintf(stderr," %ld) %lx %lx %lx\n",
  634.     i,pfx_cmap[i].red,pfx_cmap[i].green,pfx_cmap[i].blue);
  635.   }
  636.   pfx_chdr = ACT_Get_CMAP(pfx_cmap,pfx_imagec,0,pfx_imagec,0,4,4,4);
  637. }
  638.    
  639.